package datas;

import Beans.User;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;

import org.apache.ibatis.annotations.Update;

/**

 @author Marie-Claude
 */
public interface UserMapper {

  final int NB_MONTHS_INACTIVE = 6;
  final String SELECT_EMAILS = "SELECT email FROM user WHERE email=#{email}";
  final String SELECT_USER = "SELECT username FROM user WHERE username=#{username}";
  final String SELECT_USER_BY_ID = "SELECT * FROM user WHERE idUser=#{userId}";
  final String SELECT_USER_BY_USERNAME = "SELECT * FROM user WHERE username=#{username}";
  final String SELECT_EMAIL_FROM_USER_BY_ID = "SELECT email FROM user WHERE idUser=#{idUser}";
  final String SELECT_ACTIVE_USERS = "SELECT * FROM user";
  final String SELECT_USER_FAVS = "SELECT  user.idUser, username, sexe FROM user JOIN watchlist ON user.idUser=watchlist.idWatchedUser WHERE isOnWhiteList=true AND watchlist.idUser=#{userId}";
  final String SELECT_USER_PICTURES = "SELECT path FROM pictures WHERE userId=#{userId}";
  final String INSERT_USER = "INSERT INTO user (username, password, sex, rechercheSexe, age, ville, but, taille, resume, apparence, lastLogin, nbVotes, score, email) VALUES(#{username}, #{password}, #{sex}, #{lookingForSex}, #{age}, #{city}, #{goal}, #{height}, #{resume}, #{apparence}, #{lastLogin}, 0, 0, #{email})";
  final String INSER_FIRST_USER = "INSERT INTO user (username, password, sexe, age, email) VALUE (#{username},#{password},#{sex},#{age},#{email})";
  final String FAKE_DELETE_USER = "UPDATE user SET lastLogin=#{lastLogin} WHERE idUser = #{idUser}";
  final String UPDATE_ACCOUNT = "UPDATE user SET isPrivileged=#{isPrivileged} WHERE idUser = #{idUser}";
  final String UPDATE_USER_PROFILE = "UPDATE user SET isWarnedNewEmail=#{isWarnedNewEmail}, isWarnedAddWatchList=#{isWarnedAddWatchList}, password=#{password}, ville=#{ville}, age=#{age}, rechercheSexe=#{rechercheSexe}, sexe=#{sexe}, taille=#{taille}, but=#{but}, resume=#{resume}, apparence=#{apparence} WHERE idUser = #{idUser}";
  final String INSERT_PICTURES = "INSERT INTO pictures (userID, path) VALUES(#{userID}, #{path});";
  final String UPDATE_PROFILE_PICTURE = "UPDATE user SET profilePicture=#{path} where idUser=#{userID};";
  final String UPDATE_LAST_LOGIN = "UPDATE user SET lastLogin=NOW() where idUser=#{userID}";
//<editor-fold desc="User getById">

  @Select(SELECT_USER_BY_ID)
  @Results(value = {
    @Result(property = "userID", column = "idUser"),
    @Result(property = "username", column = "username"),
    //Profile photo
    @Result(property = "isWarnedByEmail", column = "isWarnedNewEmail"),
    @Result(property = "isWarnedAddWatchList", column = "isWarnedAddWatchList"),
    @Result(property = "isPrivileged", column = "isPrivileged"),
    @Result(property = "sex", column = "sexe"),
    @Result(property = "lookingForSex", column = "rechercheSexe"),
    @Result(property = "age", column = "age"),
    @Result(property = "city", column = "ville"),
    @Result(property = "goal", column = "but"),
    @Result(property = "height", column = "taille"),
    @Result(property = "resume", column = "resume"),
    @Result(property = "apparence", column = "apparence"),
    @Result(property = "lastLogin", column = "lastLogin"),
    @Result(property = "nbVotes", column = "nbVotes"),
    @Result(property = "score", column = "score")
  })
  User getById(int userId);

  //</editor-fold>
//<editor-fold desc="User getByUsername">
  @Select(SELECT_USER_BY_USERNAME)
  @Results(value = {
    @Result(property = "userID", column = "idUser"),
    @Result(property = "username", column = "username"),
    //Profile photo
    @Result(property = "password", column = "password"),
    @Result(property = "sex", column = "sexe"),
    @Result(property = "lookingForSex", column = "rechercheSexe"),
    @Result(property = "age", column = "age"),
    @Result(property = "city", column = "ville"),
    @Result(property = "goal", column = "but"),
    @Result(property = "height", column = "taille"),
    @Result(property = "resume", column = "resume"),
    @Result(property = "apparence", column = "apparence"),
    @Result(property = "lastLogin", column = "lastLogin"),
    @Result(property = "nbVotes", column = "nbVotes"),
    @Result(property = "score", column = "score"),
    @Result(property = "email", column = "email"),
    @Result(property = "isWarnedByEmail", column = "isWarnedNewEmail"),
    @Result(property = "isWarnedAddWatchList", column = "isWarnedAddWatchList"),
    @Result(property = "isPrivileged", column = "isPrivileged")

  })
  User getByUsername(String username);

  @Select("select idUser from user where username=#{username}")
  @Results(value = {
    @Result(property = "userID", column = "idUser"),
    @Result(property = "username", column = "username"),})
  int getIdByUsername(String username);

  //</editor-fold>   
//<editor-fold desc="List<User> getAllUsers"> 
  /**
   Returns a list containing all active users

   @return The list of all active users
   */
  @Select(SELECT_ACTIVE_USERS)
  @Results(value = {
    //Feel free to uncomment the properties you would need to display
    @Result(property = "userID", column = "idUser"),
    @Result(property = "username", column = "username"),
    //TODO profile picture
    //@Result(property = "password", column = "password"),
    @Result(property = "sex", column = "sexe"),
    @Result(property = "lookingForSex", column = "rechercheSexe"),
    @Result(property = "age", column = "age"),
    @Result(property = "city", column = "ville"),
    //@Result(property = "goal", column = "but"),
    //@Result(property = "height", column = "taille"),
    //@Result(property = "resume", column = "resume"),
    //@Result(property = "apparence", column = "apparence"),
    //@Result(property = "lastLogin", column = "lastLogin"),
    @Result(property = "nbVotes", column = "nbVotes"),
    @Result(property = "score", column = "score")
  //@Result(property = "email", column = "email"),
  })
  List<User> getAllUsers();
//</editor-fold>
//<editor-fold desc="List<User> selectUserFavs">

  /**
   Returns a list containing a users white listed users

   @param userId
   @return the watch list of a user
   */
  @Select(SELECT_USER_FAVS)
  @Results(value = {
    @Result(property = "userId", column = "idUser"),
    @Result(property = "username", column = "username"),
    @Result(property = "sex", column = "sexe")
  })
  List<User> selectUserFavs(int userId);
//</editor-fold>
//<editor-fold desc="List<String> selectUserPictures">

  /**
   Returns a list containing the paths for a user pictures

   @param userId
   @return the picture list of a user
   */
  @Select(SELECT_USER_PICTURES)
  List<String> selectUserPictures(int userId);
//</editor-fold>
//<editor-fold desc="Insert User">

  /**
   Insert user into DB

   @param user
   */
  @Insert(INSER_FIRST_USER)
  @Options(useGeneratedKeys = true, keyProperty = "userId")
  void insertFirstUser(User user);

  //</editor-fold>
  //<editor-fold desc="Get User Email">
  /**
   Returns the email of a user

   @param idUser
   @return The users Email
   */
  @Select(SELECT_EMAIL_FROM_USER_BY_ID)
  String getEmailFromUser(int idUser);
  //</editor-fold>

  /**
   Fake delete user from DB
   Back lastLogin

   @param lastLogin
   @param idUser
   @return int
   */
  @Update(FAKE_DELETE_USER)
  int fakeDeleteUser(@Param("lastLogin") Date lastLogin, @Param("idUser") int idUser);

  /**
   Update user into DB
   A completer password

   @param ville
   @param age
   @param rechercheSexe
   @param sexe
   @param taille
   @param but
   @param resume
   @param apparence
   @param idUser
   @param password
   @param isWarnedNewEmail
   @param isWarnedAddWatchList
   @return int
   */
  @Update(UPDATE_USER_PROFILE)
  int updateUserProfile(@Param("isWarnedNewEmail") boolean isWarnedNewEmail, @Param("isWarnedAddWatchList") boolean isWarnedAddWatchList, @Param("password") String password, @Param("ville") String ville, @Param("age") int age, @Param("rechercheSexe") String rechercheSexe, @Param("sexe") String sexe, @Param("taille") double taille, @Param("but") String but, @Param("resume") String resume, @Param("apparence") String apparence, @Param("idUser") int idUser);

  @Update(UPDATE_ACCOUNT)
  int upgradeAccount(@Param("isPrivileged") boolean isPrivileged, @Param("idUser") int idUser);

  @Select(SELECT_USER_BY_ID)
  User getUserById(int userId);

  @Select(SELECT_EMAILS)
  String getEmailsByMail(String email);

  @Select(SELECT_USER)
  String getUserName(String name);

  @Insert(INSERT_PICTURES)
  void insertPicture(@Param("userID") int userID, @Param("path") String path);

  @Update(UPDATE_PROFILE_PICTURE)
  void changeProfilePicture(@Param("userID") int userID, @Param("path") String path);

  @Update(UPDATE_LAST_LOGIN)
  void updateLastLogin(@Param("userID") int userID);
}
